package yawning.mew.cat;

import yawning.mew.cat.CatModelSimState.CatTargetData;
import yawning.mew.cat.EventMeleeSwing.MeleeStats;
import yawning.mew.cat.SwipeAction.SwipeStats;
import yawning.mew.sim.SimulationEvent;

public class EventBloodInTheWaterRange extends SimulationEvent {
	CatModelSimState mState;
	private CatTargetData mTargetData;
	private boolean mCanSchedule;
	private double mTimeToDie;
	boolean mInRange = false;

	EventBloodInTheWaterRange(CatModelSimState state, CatTargetData targetData, boolean shouldSchedule) {
		super(state.mSimEngine);
		mState = state;
		mTargetData = targetData;

		mCanSchedule = state.mModel.getBloodInTheWaterTime() > 0 && state.mModel.druid.getTalent(CatModel.BLOODINTHEWATER) > 0;
		mTimeToDie = mTargetData.mDeathEv.getExpiryTime();

		if (mCanSchedule && shouldSchedule) {
			// Assuming that adds die at the same rate as raid bosses may be somewhat flawed if they have tiny amounts
			// of HP, however for those cases BitW does not matter at all since Swipe will be used.  If people care
			// enough about it, the can use the override.
			double at = mTimeToDie - (mTimeToDie * state.mModel.getBloodInTheWaterTime());

			if (at < mState.mSimEngine.getSimTime())
				throw new RuntimeException("Attempting to schedule BitW in the past");

			if (mState.mSimEngine.getSimTime() + at > mState.mSimEngine.getEndTime()) return;	// Past encounter end, don't bother scheduling.

			schedule(mTimeToDie - (mTimeToDie * state.mModel.getBloodInTheWaterTime()));
		}
	}

	public void scheduleStartTime(double time) {
		// I expect relative time (as in, "BitW lasts <time>, ending at mob death").
		if (mCanSchedule) {
			double at = (mTimeToDie - (mState.mSimEngine.getSimTime() - mTargetData.mSpawnTime)) - time;
			if (at < mState.mSimEngine.getSimTime())
				throw new RuntimeException("Attempting to schedule BitW in the past");

			if (mState.mSimEngine.getSimTime() + at > mState.mSimEngine.getEndTime()) return;	// Past encounter end, don't bother scheduling.

			schedule(at);
		}
	}

	@Override
	public void onExpire() {
		mInRange = true;

		mTotalDamageBase =
			mTargetData.mClawAction.mClawDamage +
			mTargetData.mMangleAction.mMangleDamage +
			mTargetData.mRakeAction.mRakeDamage + mTargetData.mRakeAction.mRakeDotDamage +
			mTargetData.mShredAction.mShredDamage +
			mTargetData.mRipAction.mRipDamage +
			mTargetData.mFerociousBiteAction.mBiteDamage +
			mTargetData.mMaimAction.mMaimDamage +
			mTargetData.mPounceAction.mPounceDamage +
			mTargetData.mRavageAction.mRavageDamage +
			mTargetData.mProcPhysDamage + mTargetData.mProcSpellDamage +
			mTargetData.mTier_12_2pcEv.mFieryClawsDmg;

		SwipeStats swipeStats = mState.mSwipeAction.mDamageStats.get(mTargetData.getSimulationTarget());
		if (swipeStats != null) {
			mTotalDamageBase += swipeStats.mSwipeDamage;
		}
		MeleeStats meleeStats = mState.mMeleeSwingEv.mDamageStats.get(mTargetData.getSimulationTarget());
		if (meleeStats != null) {
			mTotalDamageBase += meleeStats.mWhiteDamage + meleeStats.mFurySwipesDamage;
		}

		mTargetData.mRipAction.onBitW();
		mTargetData.mFerociousBiteAction.onBitW();
	}

	long mTotalDamageBase = 0;
}
